package com.hhxyjsj.email;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.log4j.Logger;

import com.hhxyjsj.util.VClient;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;

public class SendEmail {
    
	private VClient client = null;
	private MailHandler handler = new MailHandler();
	private int count = 1;
	private int failCount = 1;
	private static int registerFail;//记录注册邮件地址时的失败次数
	private Logger logger = Logger.getLogger(SendEmail.class);

	private String threadName = "";
	private static String testMailAddr = "";
	private String homePage;
	public SendEmail(){
		client =new VClient("GBK");
		client.setClientIsNotSafe();
	}
	
	/**
	 * 对登陆的密码进行编码
	 * @param datastr
	 * @param bassnum
	 * @return
	 */
	public String encode(String datastr, int bassnum) {
		String newdata = "",tchar = "";
		for (int  i = 0; i < datastr.length(); i++){
			tchar = (65535 + bassnum - datastr.charAt(i)) + "";
			tchar = tchar.toString();
			while(tchar.length() < 5){
				tchar = "0" + tchar;
			}
			newdata = newdata + tchar;
		}
		return newdata;
	}
	
	/**
	 * 主页面
	 * @return
	 */
	public String loadHomePage(){	
		String homePageUrl = homePage + "/default.asp";
		client.doPost(homePageUrl, null);
		String content = client.getContent();
		String picnumStr = "<input type=\"hidden\" name=\"picnum\" value=\"";
		int index;
		String picnum = "";
		if((index = content.indexOf(picnumStr)) != -1){
			picnum = content.substring(index + picnumStr.length(), index + picnumStr.length() + 4);
		}
		return picnum;
	}
	
	public boolean login(String userName,String passWord,String picNum){
		Map params = new HashMap();
		params.put("picnum", picNum);
		params.put("username", userName);
		params.put("pwhidden", passWord);
		params.put("SecEx", "false");
		params.put("saveUser", "false");
		
		String loginUrl = homePage + "/default.asp";

		client.doPost(loginUrl, params);
		String content = client.getContent();
		String str = "<frame id=f2 name=\"f2\" src=\"viewmailbox.asp?noticemsg";
//		System.out.println(content);
		if(content.indexOf(str) != -1){
			return true;
		}
		return false;
	}
	
	//http://mail2.gxdx.gov.cn/writemail.asp?GRSN=17710162
	public String writeMail(){
		Map params = new HashMap();
		params.put("GRSN", "17710162");
		
		String writeMailUrl = homePage + "/writemail.asp?GRSN=17710162";

		client.doPost(writeMailUrl, params);
		String content = client.getContent();
		System.out.println(content);
		return "";
	}
	
	private boolean sendMail(String from,String to,String subject,String text){
		Map params = new HashMap();
		params.put("AddFromAttFileString", "");
		params.put("EasyMail_BackAddress", "");
		params.put("EasyMail_Bcc", "");
		params.put("EasyMail_Cc", "");
		params.put("EasyMail_CertServer", "0");
		params.put("EasyMail_CharSet", "GB2312");
		params.put("EasyMail_From", from);//发件人
		params.put("EasyMail_Priority", "Normal");
		params.put("EasyMail_SignNo", "-1");
		params.put("EasyMail_Subject", subject);//主题
		params.put("EasyMail_Text", text);//内容
		params.put("EasyMail_TimerSend", "");
		params.put("EasyMail_To", to);//收件人
		params.put("MailName", from);//邮件名
		params.put("Mdec_EasyMail_Text1", text);//...
		params.put("needCheckCertPassword", "0");
		params.put("RichEdit_Html", "");
		params.put("RichEdit_Text", "");
		params.put("SendMode", "send");
		Calendar c = Calendar.getInstance();
		params.put("t_day", c.get(Calendar.DATE) + "");
		params.put("t_hour", "0");
		params.put("t_month", (c.get(Calendar.MONTH) + 1) + "");
		params.put("t_year", c.get(Calendar.YEAR) + "");
		params.put("useRichEditer", "false");
		
		String sendMailUrl = homePage + "/sendmail.asp?GRSN=5120816";
		client.doPost(sendMailUrl, params);
		String content = client.getContent();
//		System.out.println(content);
		if(content.indexOf("您的邮件已经发送<b>成功</b>") != -1){
			return true;
		}
		return false;
	}
	
	public int sendEmail() {
		String userName = "", passWord = "", picNum = "";
		if(Constants.DEFAULT_HOMEPAGE.equals(homePage)){
			System.out.println("【" + threadName + "】当前已经没有可用的发送邮件的服务器地址了...");
			logger.info("【" + threadName + "】当前已经没有可用的发送邮件的服务器地址了...");
			return Constants.STATUS_NO_SERVER;
		}
		boolean success;
		System.out.println("【" + threadName + "】开始从数据库获取邮件的网地址以及发件人信息...");
		logger.info("【" + threadName + "】开始从数据库获取邮件的网地址以及发件人信息...");
		Map<String,String> mailMap = handler.findAddresser(homePage);
		if(mailMap == null || mailMap.size() == 0){
			System.out.println("【" + threadName + "】没有可用的发件人地址了，开始注册新的发件人地址...");
			logger.info("【" + threadName + "】没有可用的发件人地址了，开始注册新的发件人地址...");
			registerFail = 1;
			userName = generateMailAddr();
			int registerStatus = this.registerAddresser(userName);
			if(registerStatus == Constants.REGISTER_SUCCESS){
				System.out.println("【" + threadName + "】【" + userName + "】邮件地址注册成功...");
				logger.info("【" + threadName + "】【" + userName + "】邮件地址注册成功...");
			}else{
				System.out.println("【" + threadName + "】无法注册新的邮件地址,【本线程终止】。");
				logger.info("【" + threadName + "】无法注册新的邮件地址,【本级程终止】。");
				return Constants.STATUS_REGISTER_FAILURE;
			}
			sendEmail();
		}else{
			userName = mailMap.get("mailaddr");
			passWord = mailMap.get("password");
//			host = mailMap.get("mailurl");
			while (true) {
				count = 1;
				while (count <= 3) {
					picNum = loadHomePage();
					if (picNum != null && !"".equals(picNum)) {
						break;
					}
					count++;
					try {
						Thread.sleep(5000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				if (count == 4) {
					logger.info("【" + threadName + "】无法打开登陆页面，请稍候再试...");
					System.out.println("【" + threadName + "】无法打开登陆页面，请稍候再试...");
					return Constants.STATUS_LOGIN_FAILURE;
				}
				System.out.println("【" + threadName + "】已成功打开登陆页面...");
				logger.info("【" + threadName + "】已成功打开登陆页面...");	
				passWord = encode(passWord, Integer.parseInt(picNum));
				//登陆
				success = login(userName, passWord, picNum);
				if (success) {
					System.out.println("【" + threadName + "】【" + userName + "】成功登陆系统...");
					logger.info("【" + threadName + "】【" + userName + "】成功登陆系统...");
					break;
				}
				System.out.println("【" + threadName + "】【" + userName + "】第【" + failCount + "】次登陆失败...");
				logger.info("【" + threadName + "】第【" + failCount + "】次登陆失败...");
				if(failCount == 5){
					return Constants.STATUS_LOGIN_FAILURE;
				}
				failCount ++;
			}
//			System.out.println("【" + threadName + "】开始准备发送邮件...");
			logger.info("【" + threadName + "】开始准备发送邮件...");	
			String subject = MailUtils.getMailSubject();
			if(subject == null || "".equals(subject)){
				System.out.println("【" + threadName + "】邮件主题为空,因此不能继续往下执行...");
				return Constants.STATUS_SUBJECT_IS_NULL;
			}
			String text = MailUtils.getMailContent();
			if(text == null || "".equals(text)){
				System.out.println("【" + threadName + "】邮件内容为空,因此不能继续往下执行...");
				return Constants.STATUS_CONTENT_IS_NULL;
			}
			List<String> eList = null;
			int i = 1;
			
			if(testMailAddr != null && !"".equals(testMailAddr)){
				eList = new ArrayList<String>();
				eList.add(testMailAddr);
			}else{
				success = handler.updateIsUsed(userName,Constants.ISUSED_1);
				logger.info("【" + threadName + "】handler.updateIsUsed=" + success );
				eList = handler.getAddressee();
			}
			logger.info("【" + threadName + "】eList=" + (eList != null ? eList.size() : "空"));
			if (eList != null && eList.size() > 0) {
				for (String to : eList) {
					success = this.sendMail(userName, to, subject, text);
					if (success) {
						logger.info("【" + threadName + "】【" + to + "】邮件发送成功...");
						System.out.println("【" + threadName + "】【" + to + "】邮件发送成功...");
					} else {
						logger.info("【" + threadName + "】【" + to + "】邮件发送失败...");
						System.out.println("【" + threadName + "】【" + to + "】邮件发送失败...");
					}
					System.out.println("【" + threadName + "】当前已经发完第【" + i + "】批,暂停【" + MailUtils.getWaitTime() / 1000 +"】秒后继续...");
					i ++;
					try {
						Thread.sleep(MailUtils.getWaitTime());
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				if(testMailAddr != null && !"".equals(testMailAddr)){
					System.out.println("【" + threadName + "】测试完成!");
					return Constants.STATUS_TEST;
				}
				handler.updateIsUsed(userName,Constants.ISUSED_2);
				this.receiverMail();
//				sendEmail();
				return Constants.STATUS_SEND_FINISH;
			} else {
				logger.info("【" + threadName + "】从数据库中不存在收件人email地址,【该线程终止】。");
				System.out.println("【" + threadName + "】从数据库中不存在收件人email地址,【该线程终止】。");
				return Constants.STATUS_ADDRESSEE_IS_NULL;
			}
		}
		return Constants.STATUS_OTHER;

	}
	
	public void receiverMail(){
		String receiver = homePage + "/listmail.asp?mode=in&GRSN=27470415";
		client.doPost(receiver, null);
		String content = client.getContent();
		//<input type="checkbox" name="check0" value="20120205193150300_14120~ad212807.in">
		Pattern p = Pattern.compile("parent.f1.document.leftval.temp.value=\"[0-9a-zA-Z_.~\\s]*\"");
		Matcher m = p.matcher(content);
		if(m.find()){
			String value = m.group();
			if(!"parent.f1.document.leftval.temp.value=\"\"".equals(value)){
				value = value.substring("parent.f1.document.leftval.temp.value=\"".length() + 1, value.length() - 1);
				String[] str = value.split("\\s");
				if(str != null && str.length > 0){
					int group = 0,len = str.length;
					if(str.length % 10 == 0){
						group = len / 10;
					}else{
						group = len / 10 + 1; 
					}
					System.out.println("【" + threadName + "】开始删除收件箱中无用的邮件...");
					logger.info("【" + threadName + "】开始删除收件箱中无用的邮件...");
					for(int i = 0;i < group;i++){
						String[] s = new String[10];
						for(int j = 0;j < 10;j++){
							s[j] = len > (i * 10 + j) ? s[j] = str[i * 10 + j] : "";
						}
						boolean success = deleteMail(s);
					}
					System.out.println("【" + threadName + "】收件箱的邮件删除完成...");
					logger.info("【" + threadName + "】收件箱的邮件删除完成...");
				}
			}else{
				System.out.println("【" + threadName + "】收件箱中没有需要删除的邮件...");
				logger.info("【" + threadName + "】收件箱中没有需要删除的邮件...");
			}
		}
	}
	
	public boolean deleteMail(String... vals){
		String deleteMailUrl = homePage + "/mulmail.asp";
		int len = vals.length;
		Map params = new HashMap();
		for(int i = 0;i < 10;i++){
			params.put("check" + i, len > i ? vals[i]:"");
		}
		params.put("gourl", "listmail.asp?mode=in&sname=&sfname=&page=0&GRSN=9348413&sortstr=&sortmode=0&exstr=0000000");
		params.put("isremove", "1");
		params.put("mode", "del");
		params.put("mto", "");
		params.put("page", "0");
		client.doPost(deleteMailUrl, params);
		String content = client.getContent();
		if(content.indexOf("您的操作<b>成功</b>") != -1){
			return true;
		}
		return false;
	}
	
	public int registerAddresser(String userName){
//		String reeisterHost = "http://mail.wgao.cn/";
		String registerUrl = homePage + "/create.asp?GRSN=8829418";
		Map params = new HashMap();
		params.put("domain", "system.mail");
		params.put("username", userName);
		params.put("pw", "123456");
		params.put("pw1", "123456");
		client.doPost(registerUrl, params);
		String content = client.getContent();
		if(content.indexOf("创建成功") != -1){
			handler.addAddresser(homePage, userName, "123456");
			System.out.println("【" + threadName + "】【" + userName + "】邮件地址注册成功...");
			logger.info("【" + threadName + "】【" + userName + "】邮件地址注册成功...");
			return Constants.REGISTER_SUCCESS;
		}else if(content.indexOf("系统中已有此用户") != -1){
			System.out.println("【" + threadName + "】【" + userName + "】邮件地址已经存在，请重新注册新的用户...");
			logger.info("【" + threadName + "】【" + userName + "】邮件地址已经存在，请重新注册新的用户...");
			userName = generateMailAddr();
			registerFail = 0;
			return registerAddresser(generateMailAddr());
		}else if(registerFail > 3){
			System.out.println("【" + threadName + "】【" + homePage + "】网站无法注册新的邮件地址...");
			logger.info("【" + threadName + "】【" + homePage + "】网站无法注册新的邮件地址...");
			return Constants.REGISTER_FAILURE;
		}
		registerFail ++;
		return registerAddresser(userName);
	}
	
	private String generateMailAddr(){
		char c1 = (char)(Math.random() * 26 + 'a');
		char c2 = (char)(Math.random() * 26 + 'a');
		char c3 = (char)(Math.random() * 26 + 'a');
		return "" + c1 + c2 + c3 + System.currentTimeMillis();
	}
	
	private class SendEmailThread implements Runnable{
		
		public SendEmailThread(String _threadName){
			threadName = _threadName;
		}
		
		public void run() {
			while(true){
				homePage = MailUtils.getHomePage();
				failCount = 1;
				System.out.println("【" + threadName + "】*************************************");
				logger.info("【" + threadName + "】*************************************");
				System.out.println("【" + threadName + "】开始使用【" + homePage + "】邮件服务器...");
				logger.info("【" + threadName + "】开始使用【" + homePage + "】邮件服务器...");
				for(int i = 1;i <= MailUtils.getMailServerSendBatch();i++){
					int status = sendEmail();
//					System.out.println("【" + threadName + "】" + status + "...");
					logger.info("【" + threadName + "】发送状态:" + status + "...");
					if(status == Constants.STATUS_NO_SERVER							
							||status == Constants.STATUS_SUBJECT_IS_NULL
							||status == Constants.STATUS_CONTENT_IS_NULL
							||status == Constants.STATUS_ADDRESSEE_IS_NULL){
						System.out.println("【" + threadName + "】线程执行结束...");
						logger.info("【" + threadName + "】线程执行结束...");
						return;
					}else if(status == Constants.STATUS_LOGIN_FAILURE 
							|| status == Constants.STATUS_REGISTER_FAILURE
							||status == Constants.STATUS_OTHER){
						break;
					}
				}

				MailUtils.addUsedEmailServerAddress(homePage);
				System.out.println("【" + threadName + "】【" + homePage + "】邮件服务器使用结束...");
				logger.info("【" + threadName + "】开始采用【" + homePage + "】邮件服务器使用结束...");
				System.out.println("【" + threadName + "】*************************************");
				logger.info("【" + threadName + "】*************************************");
			}
		}
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		SendEmail sendEmail = new SendEmail();
		/*String mailAddr = sendEmail.generateMailAddr();
		mailAddr = new Base64().encode(mailAddr.getBytes());
		System.out.println(mailAddr);*/
		//Z21nMTMyODcwODkyMDY4Nw==
        //ZmVmMTMyODcwODkzODQ2OA==

		
		testMailAddr = MailUtils.getTestMailAddr();
		if(testMailAddr != null && !"".equals(testMailAddr)){
			sendEmail.threadName = "测试线程";
			sendEmail.homePage = MailUtils.getTestHomePage();
			sendEmail.sendEmail();
		}else{
			sendEmail.handler.updateIsUsed();
			for(int i = 1; i <= MailUtils.getThreadNum();i++){
				new Thread(new SendEmail().new SendEmailThread("Thread-" + i)).start();
				try {
					Thread.sleep(10000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
//		sendEmail.receiverMail();
		/*String str = "<a href=\"viewthread.php?tid=413071&amp;extra=page%3D1\" style=\"font-weight: bold;color\"";	    
		Pattern p = Pattern.compile("href=\"[0-9a-zA-Z%.;?/=&;]*\"");
		Matcher m = p.matcher(str);
		if(m.find()){
			String href = m.group();
			System.out.println(href);
		}*/
	}
}
